package im.elephas.androfan.fanfouapi;

import im.elephas.androfan.fanfouapi.events.IChangeEvent;
import im.elephas.androfan.fanfouapi.events.IErrorEvent;
import im.elephas.androfan.fanfouapi.events.IStatusesEvent;
import im.elephas.androfan.fanfouapi.events.IUpdateEvent;
import im.elephas.androfan.fanfouapi.events.IUsersEvent;
import im.elephas.androfan.fanfouapi.events.IVerifyEvent;
import im.elephas.androfan.fanfouapi.items.StatusItem;
import im.elephas.androfan.fanfouapi.items.UserItem;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.zip.GZIPInputStream;

import org.apache.http.HeaderElement;
import org.apache.http.HttpException;
import org.apache.http.HttpRequest;
import org.apache.http.HttpRequestInterceptor;
import org.apache.http.HttpResponse;
import org.apache.http.HttpVersion;
import org.apache.http.NameValuePair;
import org.apache.http.ParseException;
import org.apache.http.auth.AuthScheme;
import org.apache.http.auth.AuthScope;
import org.apache.http.auth.AuthState;
import org.apache.http.auth.UsernamePasswordCredentials;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.CredentialsProvider;
import org.apache.http.client.HttpClient;
import org.apache.http.client.HttpResponseException;
import org.apache.http.client.ResponseHandler;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.protocol.ClientContext;
import org.apache.http.conn.ClientConnectionManager;
import org.apache.http.conn.params.ConnManagerParams;
import org.apache.http.conn.scheme.PlainSocketFactory;
import org.apache.http.conn.scheme.Scheme;
import org.apache.http.conn.scheme.SchemeRegistry;
import org.apache.http.conn.ssl.SSLSocketFactory;
import org.apache.http.entity.FileEntity;
import org.apache.http.entity.mime.HttpMultipartMode;
import org.apache.http.entity.mime.MIME;
import org.apache.http.entity.mime.MultipartEntity;
import org.apache.http.entity.mime.content.ContentBody;
import org.apache.http.entity.mime.content.FileBody;
import org.apache.http.entity.mime.content.InputStreamBody;
import org.apache.http.entity.mime.content.StringBody;
import org.apache.http.impl.auth.BasicScheme;
import org.apache.http.impl.client.BasicResponseHandler;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.impl.conn.tsccm.ThreadSafeClientConnManager;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.params.BasicHttpParams;
import org.apache.http.params.HttpParams;
import org.apache.http.params.HttpProtocolParams;
import org.apache.http.protocol.BasicHttpContext;
import org.apache.http.protocol.HTTP;
import org.apache.http.protocol.HttpContext;
import org.apache.james.mime4j.message.Entity;
import org.xmlpull.v1.XmlPullParserException;

import android.net.Credentials;

public final class FanfouApi {

	private static class GzipResponseHandler implements ResponseHandler<String> {

		@Override
		public String handleResponse(HttpResponse response)
				throws ClientProtocolException, IOException {
			GZIPInputStream gis = new GZIPInputStream(response.getEntity()
					.getContent());
			ByteArrayOutputStream baos = new ByteArrayOutputStream();
			byte[] buf = new byte[2048];

			int num = gis.read(buf);
			while (num != -1) {
				baos.write(buf, 0, num);
				num = gis.read(buf);
			}
			gis.close();
			return baos.toString();
		}
	}

	private static class PreemptiveAuth implements HttpRequestInterceptor {

		@Override
		public void process(final HttpRequest request, final HttpContext context)
				throws HttpException, IOException {

			AuthState authState = (AuthState) context
					.getAttribute(ClientContext.TARGET_AUTH_STATE);

			if (authState.getAuthScheme() == null) {
				AuthScheme authScheme = (AuthScheme) context
						.getAttribute("preemptive-auth");
				CredentialsProvider credsProvider = (CredentialsProvider) context
						.getAttribute(ClientContext.CREDS_PROVIDER);
				if (authScheme != null) {
					org.apache.http.auth.Credentials creds = credsProvider
							.getCredentials(AuthScope.ANY);
					if (creds == null) {
						throw new HttpException();
					}
					authState.setAuthScheme(authScheme);
					authState.setCredentials(creds);
				}
			}
		}
	}

	public final static String OPERATION_MORE = "more";

	public final static String OPERATION_REFRESH = "refresh";

	private volatile static FanfouApi mFanfouApi;

	public static FanfouApi getInstance() {
		if (mFanfouApi == null) {
			synchronized (FanfouApi.class) {
				if (mFanfouApi == null) {
					mFanfouApi = new FanfouApi();
				}
			}
		}
		return mFanfouApi;
	}

	private List<String> firendsListIds;

	private List<String> followersListIds;

	private List<StatusItem> friendsStatusesList = new LinkedList<StatusItem>();

	private DefaultHttpClient mHttpClient;

	private BasicHttpContext mHttpContext;

	private String password;

	private List<StatusItem> replyStatusesList = new LinkedList<StatusItem>();

	private UserItem user;

	private String username;

	private List<StatusItem> userStatusesList = new LinkedList<StatusItem>();

	private FanfouApi() {
	}

	public void backTrackingMessage(final String id, final IStatusesEvent ise,
			final IErrorEvent iee) {
		Thread t = new Thread(new Runnable() {
			@Override
			public void run() {
				try {
					List<StatusItem> lsi = new LinkedList<StatusItem>();
					String nid = id;
					while (true) {
						try {
							String xml = getStringFromApi(FanfouUrl.FANFOU_STATUES_SHOW

									+ nid + ".xml");
							List<StatusItem> statuses = FanfouXml
									.getStatuses(xml);
							lsi.add(statuses.get(0));
							if (statuses.get(0).getInReplyToStatusId() == "")
								break;
							nid = statuses.get(0).getInReplyToStatusId();
						} catch (Exception e) {
							e.printStackTrace();
							break;
						}
					}
					ise.statusesHandler(lsi);
				} catch (Exception e) {
					iee.errorHandler();
				}
			}
		});
		t.start();
	}

	public Object clone() throws CloneNotSupportedException {
		throw new CloneNotSupportedException();
	}

	public void createFavorite(final String id, final IChangeEvent ice,
			final IErrorEvent iee) {
		Thread t = new Thread(new Runnable() {
			@Override
			public void run() {
				try {
					List<NameValuePair> nvps = new ArrayList<NameValuePair>();
					nvps.add(new BasicNameValuePair("id", id));
					updateMessageToApi(FanfouUrl.FANFOU_FAVORTITES_CREATE + id
							+ ".xml", nvps);
					ice.changeHandler(true);
				} catch (Exception e) {
					iee.errorHandler();
				}
			}
		});
		t.start();
	}

	public void createFriendship(final String id, final IChangeEvent ice,
			final IErrorEvent iee) {
		Thread t = new Thread(new Runnable() {
			@Override
			public void run() {
				try {
					List<NameValuePair> nvps = new ArrayList<NameValuePair>();
					nvps.add(new BasicNameValuePair("id", id));
					updateMessageToApi(FanfouUrl.FANFOU_FRIENDSHIPS_CREATE,
							nvps);
					updateFriendIds(mFanfouApi.getUser().getId());
					ice.changeHandler(true);
				} catch (Exception e) {
					iee.errorHandler();
				}
			}
		});
		t.start();
	}

	public void destroyFavorite(final String id, final IChangeEvent ice,
			final IErrorEvent iee) {
		Thread t = new Thread(new Runnable() {
			@Override
			public void run() {
				try {
					List<NameValuePair> nvps = new ArrayList<NameValuePair>();
					nvps.add(new BasicNameValuePair("id", id));
					updateMessageToApi(FanfouUrl.FANFOU_FAVORTITES_DESTROY + id
							+ ".xml", nvps);
					ice.changeHandler(true);
				} catch (Exception e) {
					iee.errorHandler();
				}
			}
		});
		t.start();
	}

	public void destroyFriendship(final String id, final IChangeEvent ice,
			final IErrorEvent iee) {
		Thread t = new Thread(new Runnable() {
			@Override
			public void run() {
				try {
					List<NameValuePair> nvps = new ArrayList<NameValuePair>();
					nvps.add(new BasicNameValuePair("id", id));
					updateMessageToApi(FanfouUrl.FANFOU_FRIENDSHIPS_DESTROY,
							nvps);
					updateFriendIds(mFanfouApi.getUser().getId());
					ice.changeHandler(true);
				} catch (Exception e) {
					iee.errorHandler();
				}
			}
		});
		t.start();
	}

	public void destroyStatus(final String id, final IChangeEvent ice,
			final IErrorEvent iee) {
		Thread t = new Thread(new Runnable() {
			@Override
			public void run() {
				try {
					List<NameValuePair> nvps = new ArrayList<NameValuePair>();
					nvps.add(new BasicNameValuePair("id", id));
					updateMessageToApi(FanfouUrl.FANFOU_STATUES_DESTROY + id
							+ ".xml", nvps);
					for (StatusItem item : userStatusesList) {
						if (item.getId() == id) {
							userStatusesList.remove(item);
							break;
						}
					}
					for (StatusItem item : friendsStatusesList) {
						if (item.getId() == id) {
							friendsStatusesList.remove(item);
							break;
						}
					}
					ice.changeHandler(true);
				} catch (Exception e) {
					e.printStackTrace();
					iee.errorHandler();
				}
			}
		});
		t.start();
	}

	public void getFavorite(final int count, final int page,
			final IStatusesEvent ise, final IErrorEvent iee) {
		Thread t = new Thread(new Runnable() {

			@Override
			public void run() {
				String xml = null;
				try {
					xml = getStringFromApi(FanfouUrl.FANFOU_FAVORTITES
							+ "?count=" + count + "&page=" + page);
					ise.statusesHandler(FanfouXml.getStatuses(xml));
				} catch (Exception e) {
					iee.errorHandler();
				}
			}
		});
		t.start();
	}

	public List<String> getFirendsListIds() {
		return firendsListIds;
	}

	public void getFollowers(final String id, final IUsersEvent iue,
			final IErrorEvent iee) {
		Thread t = new Thread(new Runnable() {
			@Override
			public void run() {
				try {
					String str = getStringFromApi(FanfouUrl.FANFOU_USERS_FOLLOWERS
							+ "?id=" + id);
					List<UserItem> lui = FanfouXml.getUsers(str);
					iue.usersHandler(lui);
				} catch (Exception e) {
					iee.errorHandler();
				}
			}
		});
		t.start();
	}

	public List<String> getFollowersListIds() {
		return followersListIds;
	}

	public void getFriends(final String id, final IUsersEvent iue,
			final IErrorEvent iee) {
		Thread t = new Thread(new Runnable() {
			@Override
			public void run() {
				try {
					String str = getStringFromApi(FanfouUrl.FANFOU_USERS_FOLLOWERS
							+ "?id=" + id);
					List<UserItem> lui = FanfouXml.getUsers(str);
					iue.usersHandler(lui);
				} catch (Exception e) {
					e.printStackTrace();
					iee.errorHandler();
				}
			}
		});
		t.start();
	}

	public List<StatusItem> getFriendsStatusesList() {
		return friendsStatusesList;
	}

	public void getFriendsTimeline(final int count, final IStatusesEvent ise,
			final IErrorEvent iee, final String so) {
		// TODO
		Thread t = new Thread(new Runnable() {

			@Override
			public void run() {
				if (so == OPERATION_REFRESH) {
					String xml = null;
					try {
						if (friendsStatusesList.size() != 0)
							xml = getStringFromApi(FanfouUrl.FANFOU_STATUES_FRIENDS_TIMELINE
									+ "?count="
									+ count
									+ "&since_id="
									+ friendsStatusesList.get(0).getId());
						else
							xml = getStringFromApi(FanfouUrl.FANFOU_STATUES_FRIENDS_TIMELINE
									+ "?count=" + count);
						List<StatusItem> statuses = FanfouXml.getStatuses(xml);
						insertUserItems(friendsStatusesList, statuses, 0);
						ise.statusesHandler(friendsStatusesList);
					} catch (Exception e) {
						e.printStackTrace();
						iee.errorHandler();
					}
				} else {
					String xml = null;
					try {
						if (friendsStatusesList.size() != 0)
							xml = getStringFromApi(FanfouUrl.FANFOU_STATUES_FRIENDS_TIMELINE
									+ "?count="
									+ count
									+ "&max_id="
									+ friendsStatusesList.get(
											friendsStatusesList.size() - 1)
											.getId());
						else
							xml = getStringFromApi(FanfouUrl.FANFOU_STATUES_FRIENDS_TIMELINE
									+ "?count=" + count);
						List<StatusItem> statuses = FanfouXml.getStatuses(xml);
						appendUserItems(friendsStatusesList, statuses);
						ise.statusesHandler(friendsStatusesList);
					} catch (Exception e) {
						e.printStackTrace();
						iee.errorHandler();
					}
				}
			}
		});
		t.start();
	}

	public String getPassword() {
		return password;
	}

	public void getPublicTimeline(final int count, final IStatusesEvent ise,
			final IErrorEvent iee) {
		Thread t = new Thread(new Runnable() {

			@Override
			public void run() {
				String xml = null;
				try {
					xml = getStringFromApi(FanfouUrl.FANFOU_STATUES_PUBLIC_TIMELINE
							+ "?count=" + count);
					ise.statusesHandler(FanfouXml.getStatuses(xml));
				} catch (Exception e) {
					iee.errorHandler();
				}
			}
		});
		t.start();
	}

	public List<StatusItem> getReplyStatusesList() {
		return replyStatusesList;
	}

	public void getReplyTimeline(final int count, final IStatusesEvent ise,
			final IErrorEvent iee, final String so) {
		// TODO
		Thread t = new Thread(new Runnable() {

			@Override
			public void run() {
				if (so == OPERATION_REFRESH) {
					String xml = null;
					try {
						if (replyStatusesList.size() != 0)
							xml = getStringFromApi(FanfouUrl.FANFOU_STATUES_REPLIES
									+ "?count="
									+ count
									+ "&since_id="
									+ replyStatusesList.get(0).getId());
						else
							xml = getStringFromApi(FanfouUrl.FANFOU_STATUES_REPLIES
									+ "?count=" + count);
						List<StatusItem> statuses = FanfouXml.getStatuses(xml);
						insertUserItems(replyStatusesList, statuses, 0);
						ise.statusesHandler(replyStatusesList);
					} catch (Exception e) {
						e.printStackTrace();
						iee.errorHandler();
					}
				} else {
					String xml = null;
					try {
						if (replyStatusesList.size() != 0)
							xml = getStringFromApi(FanfouUrl.FANFOU_STATUES_REPLIES
									+ "?count="
									+ count
									+ "&max_id="
									+ replyStatusesList.get(
											replyStatusesList.size() - 1)
											.getId());
						else
							xml = getStringFromApi(FanfouUrl.FANFOU_STATUES_REPLIES
									+ "?count=" + count);
						List<StatusItem> statuses = FanfouXml.getStatuses(xml);
						appendUserItems(replyStatusesList, statuses);
						ise.statusesHandler(replyStatusesList);
					} catch (Exception e) {
						e.printStackTrace();
						iee.errorHandler();
					}

				}
			}
		});
		t.start();
	}

	public UserItem getUser() {
		return user;
	}

	public String getUsername() {
		return username;
	}

	public List<StatusItem> getUserStatusesList() {
		return userStatusesList;
	}

	public void getUserTimeline(final int count, final IStatusesEvent ise,
			final IErrorEvent iee, final String so) {
		Thread t = new Thread(new Runnable() {

			@Override
			public void run() {
				if (so == OPERATION_REFRESH) {
					String xml = null;
					try {
						if (userStatusesList.size() != 0)
							xml = getStringFromApi(FanfouUrl.FANFOU_STATUES_USER_TIMELINE
									+ "?count="
									+ count
									+ "&since_id="
									+ userStatusesList.get(0).getId());
						else
							xml = getStringFromApi(FanfouUrl.FANFOU_STATUES_USER_TIMELINE
									+ "?count=" + count);
						List<StatusItem> statuses = FanfouXml.getStatuses(xml);
						insertUserItems(userStatusesList, statuses, 0);
						ise.statusesHandler(userStatusesList);
					} catch (Exception e) {
						e.printStackTrace();
						iee.errorHandler();
					}
				} else {
					String xml = null;
					try {
						if (userStatusesList.size() != 0)
							xml = getStringFromApi(FanfouUrl.FANFOU_STATUES_USER_TIMELINE
									+ "?count="
									+ count
									+ "&max_id="
									+ userStatusesList.get(
											userStatusesList.size() - 1)
											.getId());
						else
							xml = getStringFromApi(FanfouUrl.FANFOU_STATUES_USER_TIMELINE
									+ "?count=" + count);
						List<StatusItem> statuses = FanfouXml.getStatuses(xml);
						appendUserItems(userStatusesList, statuses);
						ise.statusesHandler(userStatusesList);
					} catch (Exception e) {
						e.printStackTrace();
						iee.errorHandler();
					}
				}
			}
		});
		t.start();
	}

	public void getUserTimeline(final int count, final String id,
			final IStatusesEvent ise, final IErrorEvent iee) {
		// TODO
		Thread t = new Thread(new Runnable() {

			@Override
			public void run() {
				String xml = null;
				try {
					xml = getStringFromApi(FanfouUrl.FANFOU_STATUES_USER_TIMELINE
							+ "?count=" + count + "&id=" + id);
					List<StatusItem> statuses = FanfouXml.getStatuses(xml);
					ise.statusesHandler(statuses);
				} catch (Exception e) {
					e.printStackTrace();
					iee.errorHandler();
				}
			}
		});
		t.start();
	}

	public void loginAccount(final IVerifyEvent ive) {
		Thread t = new Thread(new Runnable() {
			@Override
			public void run() {
				try {
					String str = getStringFromApi(FanfouUrl.FANFOU_ACCOUNT_VERIFY);
					List<UserItem> lu = FanfouXml.getUsers(str);
					if (lu.get(0) != null) {
						mFanfouApi.user = lu.get(0);
						updateFriendIds(mFanfouApi.getUser().getId());
						updateFollowerIds(mFanfouApi.getUser().getId());
						ive.verifyHandler(true);
					} else
						ive.verifyHandler(false);
				} catch (Exception e) {
					e.printStackTrace();
					ive.verifyHandler(false);
				}
			}
		});
		t.start();
	}

	public void refanfouMessage(final String status, final String id,
			final IUpdateEvent iue, final IErrorEvent iee) {
		Thread t = new Thread(new Runnable() {
			@Override
			public void run() {
				try {
					ArrayList<NameValuePair> nvps = new ArrayList<NameValuePair>();
					nvps.add(new BasicNameValuePair("status", status));
					nvps.add(new BasicNameValuePair("repost_status_id", id));
					nvps.add(new BasicNameValuePair("source", "androfan"));
					String str = updateMessageToApi(
							FanfouUrl.FANFOU_STATUES_UPDATE, nvps);
					iue.updateHandler(str);
				} catch (Exception e) {
					iee.errorHandler();
				}
			}
		});
		t.start();
	}

	public void replyMessage(final String status, final String replyId,
			final IUpdateEvent iue, final IErrorEvent iee) {
		Thread t = new Thread(new Runnable() {
			@Override
			public void run() {
				try {
					ArrayList<NameValuePair> nvps = new ArrayList<NameValuePair>();
					nvps.add(new BasicNameValuePair("status", status));
					nvps.add(new BasicNameValuePair("in_reply_to_status_id",
							replyId));
					nvps.add(new BasicNameValuePair("source", "androfan"));
					String str = updateMessageToApi(
							FanfouUrl.FANFOU_STATUES_UPDATE, nvps);
					iue.updateHandler(str);
				} catch (Exception e) {
					iee.errorHandler();
				}
			}
		});
		t.start();

	}

	public void setAccount(String username, String password) {
		this.username = username;
		this.password = password;

		HttpParams params = new BasicHttpParams();
		ConnManagerParams.setMaxTotalConnections(params, 100);
		HttpProtocolParams.setVersion(params, HttpVersion.HTTP_1_1);

		SchemeRegistry schemeRegistry = new SchemeRegistry();
		schemeRegistry.register(new Scheme("http", PlainSocketFactory
				.getSocketFactory(), 80));
		schemeRegistry.register(new Scheme("https", SSLSocketFactory
				.getSocketFactory(), 443));

		ClientConnectionManager cm = new ThreadSafeClientConnManager(params,
				schemeRegistry);

		mHttpClient = new DefaultHttpClient(cm, params);
		mHttpClient.getCredentialsProvider().setCredentials(AuthScope.ANY,
				new UsernamePasswordCredentials(username, password));
		mHttpClient.addRequestInterceptor(new PreemptiveAuth(), 0);
		mHttpContext = new BasicHttpContext();
		BasicScheme basicAuth = new BasicScheme();
		mHttpContext.setAttribute("preemptive-auth", basicAuth);

	}

	public void updateMessage(final String status, final IUpdateEvent iue,
			final IErrorEvent iee) {
		Thread t = new Thread(new Runnable() {
			@Override
			public void run() {
				try {
					ArrayList<NameValuePair> nvps = new ArrayList<NameValuePair>();
					nvps.add(new BasicNameValuePair("status", status));
					nvps.add(new BasicNameValuePair("source", "androfan"));
					String str = updateMessageToApi(
							FanfouUrl.FANFOU_STATUES_UPDATE, nvps);
					iue.updateHandler(str);
				} catch (Exception e) {
					iee.errorHandler();
				}
			}
		});
		t.start();
	}

	public void updateMessageWithPhoto(final String status, final File file,
			final IUpdateEvent iue, final IErrorEvent iee) {
		Thread t = new Thread(new Runnable() {
			@Override
			public void run() {
				try {
					ArrayList<NameValuePair> nvps = new ArrayList<NameValuePair>();
					nvps.add(new BasicNameValuePair("status", status));
					nvps.add(new BasicNameValuePair("source", "androfan"));
					Map<String, File> map = new HashMap<String, File>();
					map.put("photo", file);
					updateMessageToApiWithData(FanfouUrl.FANFOU_PHOTO_UPDATE,
							map, nvps);
				} catch (Exception e) {
					iee.errorHandler();
				}
			}
		});
		t.start();
	}

	private void appendUserItems(List<StatusItem> toLui,
			List<StatusItem> fromLui) {

		toLui.addAll(fromLui);
	}

	private boolean deleteUserItemElement(List<StatusItem> toLui, UserItem ui) {
		if (toLui.contains(ui)) {
			toLui.remove(ui);
			return true;
		}
		return false;
	}

	private String getStringFromApi(String api) throws ClientProtocolException,
			IOException {
		HttpGet httpget = new HttpGet(api);
		httpget.setHeader("Accept-Encoding", "gzip, deflate");
		ResponseHandler<String> responseHandler = new GzipResponseHandler();
		String str = mHttpClient
				.execute(httpget, responseHandler, mHttpContext);
		return str;
	}

	private void insertUserItems(List<StatusItem> toLui,
			List<StatusItem> fromLui, int at) {
		toLui.addAll(at, fromLui);
	}

	private void updateFollowerIds(final String id)
			throws ClientProtocolException, IOException, XmlPullParserException {
		String str = getStringFromApi(FanfouUrl.FANFOU_FOLLOWERS_IDS + id
				+ ".xml");
		List<String> ls = FanfouXml.getIds(str);
		followersListIds = ls;
	}

	private void updateFriendIds(final String id)
			throws ClientProtocolException, IOException, XmlPullParserException {
		String str = getStringFromApi(FanfouUrl.FANFOU_FRIENDS_IDS + id
				+ ".xml");
		List<String> ls = FanfouXml.getIds(str);
		firendsListIds = ls;
	}

	private String updateMessageToApi(String api, List<NameValuePair> nvps)
			throws ClientProtocolException, IOException {
		HttpPost httppost = new HttpPost(api);
		httppost.setHeader("Accept-Encoding", "gzip, deflate");
		httppost.setEntity(new UrlEncodedFormEntity(nvps, HTTP.UTF_8));
		ResponseHandler<String> responseHandler = new GzipResponseHandler();
		String str = mHttpClient.execute(httppost, responseHandler,
				mHttpContext);
		return str;
	}

	private String updateMessageToApiWithData(String api,
			Map<String, File> data, List<NameValuePair> nvps)
			throws ClientProtocolException, IOException {
		HttpPost httppost = new HttpPost(api);
		httppost.setHeader("Accept-Encoding", "gzip, deflate");
		MultipartEntity entity = new MultipartEntity();
		for (NameValuePair item : nvps)
			entity.addPart(item.getName(), new StringBody(item.getValue()));
		for (String item : data.keySet())
			entity.addPart(item, new FileBody(data.get(item)));
		ResponseHandler<String> responseHandler = new GzipResponseHandler();
		String str = mHttpClient.execute(httppost, responseHandler,
				mHttpContext);
		return str;
	}
}
